﻿// Copyright (c) Inossem. All rights reserved.
// Licensed under the LGPL-3.0 license. See LICENSE file in the project root for full license information.
using DWF.Studio.ScriptEngine.IPC.Msg;
using DWF.Studio.Share.Log;
using NamedPipeWrapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DWF.Studio.ScriptEngine.IPC.NamedPipe
{
    /// <summary>
    /// 命名管道客户端
    /// </summary>
    public class NamedPipeClient
    {
        /// <summary>
        /// 接收消息
        /// </summary>
        public Action<DownwardMsg> ReceiveMessage
        {
            set;
            get;
        }

        /// <summary>
        /// 未处理错误
        /// </summary>
        public Action<Exception> UnhandleError
        {
            set;
            get;
        }

        private string _pipeName = "RemoteEnginePipe";

        /// <summary>
        /// 管道名
        /// </summary>
        public string PipeName
        {
            get
            {
                return _pipeName;
            }
        }

        /// <summary>
        /// 管道客户端
        /// </summary>
        private NamedPipeClientExAsync<DownwardMsg, UpwardMsg> _pipeClient = null;

        /// <summary>
        /// 
        /// </summary>
        public NamedPipeClient()
        {
            _pipeClient = new NamedPipeClientExAsync<DownwardMsg, UpwardMsg>(_pipeName);
            _pipeClient.ServerMessage += (connection, message) => { ReceiveMessage?.Invoke(message); };
            _pipeClient.Error += (exception) => { LogHelper.Error(exception); UnhandleError?.Invoke(exception); };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pipeName"></param>
        public NamedPipeClient(string pipeName)
        {
            _pipeName = pipeName;
            _pipeClient = new NamedPipeClientExAsync<DownwardMsg, UpwardMsg>(_pipeName);
            _pipeClient.ServerMessage += (connection, message) => { ReceiveMessage?.Invoke(message); };
            _pipeClient.Error += (exception) => { LogHelper.Error(exception); UnhandleError?.Invoke(exception); };
        }

        /// <summary>
        /// 连接
        /// </summary>
        public void Connnect()
        {
            _pipeClient.Connect();
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="timeout"></param>
        public void Connnect(int timeout)
        {
            _pipeClient.Connect(timeout);
        }

        /// <summary>
        /// 异步连接
        /// </summary>
        /// <returns></returns>
        public async Task ConnnectAsync()
        {
            await _pipeClient.ConnectAsync();
        }

        /// <summary>
        /// 异步连接
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public async Task ConnnectAsync(int timeout)
        {
            await _pipeClient.ConnectAsync(timeout);
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnnect()
        {
            _pipeClient.Disconnect();
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message"></param>
        public void Send(UpwardMsg message)
        {
            _pipeClient.PushMessage(message);
        }

        /// <summary>
        /// 异步发送消息
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendAsync(UpwardMsg message)
        {
            await _pipeClient.PushMessageAsync(message);
        }
    }
}
